package com.iteaj.plc.core.net;

import com.iteaj.plc.core.types.IDataTransfer;
import com.iteaj.plc.core.types.OperateResult;
import com.iteaj.plc.core.types.OperateResultExOne;

/**
 * 读写设备操作<br />
 */
public interface IReadWriteClient {

    /**
     * 当前连接的唯一ID号，默认为长度20的guid码加随机数组成，方便列表管理，也可以自己指定<br />
     * @return 字符串信息
     */
    public String getConnectionId();

    /**
     * 设置当前的连接ID
     * @param connectionId 设置的数据信息
     */
    public void setConnectionId(String connectionId);

    // endregion

    // region Read Write Bytes

    /**
     * 批量读取字节数组信息，需要指定地址和长度，返回原始的字节数组<br />
     * @param address 数据地址
     * @param length 数据长度
     * @return 带有成功标识的byte[]数组
     */
    OperateResultExOne<byte[]> read(String address, short length );

    /**
     * 写入原始的byte数组数据到指定的地址，返回是否写入成功<br />
     * @param address 起始地址
     * @param value 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write( String address, byte[] value );

    /**
     * 批量读取 {@link Boolean} 数组信息，需要指定地址和长度，返回 {@link Boolean} 数组<br />
     * @param address 数据地址
     * @param length 数据长度
     * @return 带有成功标识的boolean[]数组
     */
    OperateResultExOne<boolean[]> readBool(String address, short length );

    /**
     * 读取单个的 {@link Boolean} 数据信息<br />
     * @param address 数据地址
     * @return 带有成功标识的boolean值
     */
    OperateResultExOne<Boolean> readBool(String address );

    // endregion

    /**
     * 读取16位的有符号的整型数据<br />
     * @param address 起始地址
     * @return 带有成功标识的short数据
     */
    OperateResultExOne<Short> readInt16(String address);

    /**
     * 读取16位的有符号整型数组<br />
     * @param address 起始地址
     * @param length 读取的数组长度
     * @return 带有成功标识的short数组
     */
    OperateResultExOne<short[]> readInt16(String address, short length );

    /**
     * 读取16位的无符号整型<br />
     * @param address 起始地址
     * @return 带有成功标识的 ushort 数据
     */
    OperateResultExOne<Integer> readUInt16(String address );

    /**
     * 读取16位的无符号整型数组<br />
     * @param address 起始地址
     * @param length 读取的数组长度
     * @return 带有成功标识的 ushort 数组
     */
    OperateResultExOne<int[]> readUInt16(String address, short length );

    /**
     * 读取32位的有符号整型<br />
     * @param address 起始地址
     * @return 带有成功标识的int数据
     */
    OperateResultExOne<Integer> readInt32(String address);

    /**
     * 读取32位有符号整型数组<br />
     * @param address 起始地址
     * @param length 数组长度
     * @return 带有成功标识的int数组
     */
    OperateResultExOne<int[]> readInt32(String address, short length );

    /**
     * 读取32位的无符号整型<br />
     * @param address 起始地址
     * @return 带有成功标识的uint数据
     */
    OperateResultExOne<Long> readUInt32(String address );

    /**
     * 读取32位的无符号整型数组<br />
     * @param address 起始地址
     * @param length 数组长度
     * @return 带有成功标识的uint数组
     */
    OperateResultExOne<long[]> readUInt32(String address, short length );

    /**
     * 读取64位的有符号整型<br />
     * @param address 起始地址
     * @return 带有成功标识的long数据
     */
    OperateResultExOne<Long> readInt64(String address);

    /**
     * 读取64位的有符号整型数组<br />
     * @param address 起始地址
     * @param length 数组长度
     * @return 带有成功标识的long数组
     */
    OperateResultExOne<long[]> readInt64(String address, short length );

    /**
     * 读取单浮点数据<br />
     * @param address 起始地址
     * @return 带有成功标识的float数据
     */
    OperateResultExOne<Float> eadFloat(String address);

    /**
     * 读取单浮点精度的数组<br />
     * @param address 起始地址
     * @param length 数组长度
     * @return 带有成功标识的float数组
     */
    OperateResultExOne<float[]> eadFloat(String address, short length );

    /**
     * 读取双浮点的数据<br />
     * @param address 起始地址
     * @return 带有成功标识的double数据
     */
    OperateResultExOne<Double> readDouble(String address);


    /**
     * 读取双浮点数据的数组<br />
     * @param address 起始地址
     * @param length 数组长度
     * @return 带有成功标识的double数组
     */
    OperateResultExOne<double[]> readDouble(String address, short length );

    /**
     * 读取字符串数据，默认为最常见的ASCII编码<br />
     * @param address 起始地址
     * @param length 数据长度
     * @return 带有成功标识的string数据
     */
    OperateResultExOne<String> readString(String address, short length);

    /**
     * 使用指定的编码，读取字符串数据<br />
     * @param address 起始地址
     * @param length 数据长度
     * @param encoding 指定的自定义的编码
     * @return 带有成功标识的string数据
     */
    OperateResultExOne<String> readString(String address, short length, String encoding );

    /**
     * 读取自定义的数据类型
     * @param address 起始地址
     * @param <T> 自定义的类型
     * @return 带有成功标识的自定义类型数据
     */
    <T extends IDataTransfer> OperateResultExOne<T> readCustomer(String address, Class<T> tClass);

    /**
     * 批量写入 {@link Boolean} 数组数据，返回是否成功<br />
     * @param address 起始地址
     * @param value 写入值
     * @return 是否写入成功
     */
    OperateResult write( String address, boolean[] value );

    /**
     * 写入单个的 {@link Boolean} 数据，返回是否成功<br />
     * @param address 起始地址
     * @param value 写入值
     * @return 是否写入成功
     */
    OperateResult write( String address, boolean value );

    /**
     * 写入short数据，返回是否成功<br />
     * @param address 起始地址
     * @param value 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, short value);

    /**
     * 写入short数组，返回是否成功<br />
     * @param address 起始地址
     * @param values 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, short[] values);

    /**
     * 写入int数据，返回是否成功<br />
     * @param address 起始地址
     * @param value 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, int value);

    /**
     * 写入int[]数组，返回是否成功<br />
     * @param address 起始地址
     * @param values 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, int[] values);

    /**
     * 写入long数据，返回是否成功<br />
     * @param address 起始地址
     * @param value 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, long value);

    /**
     * 写入long数组，返回是否成功<br />
     * @param address 起始地址
     * @param values 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, long[] values);

    /**
     * 写入float数据，返回是否成功<br />
     * @param address 起始地址
     * @param value 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, float value);

    /**
     * 写入float数组，返回是否成功<br />
     * @param address 起始地址
     * @param values 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, float[] values);

    /**
     * 写入double数据，返回是否成功<br />
     * @param address 起始地址
     * @param value 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, double value);

    /**
     * 写入double数组，返回是否成功<br />
     * @param address 起始地址
     * @param values 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, double[] values);

    /**
     * 写入字符串信息，编码为ASCII<br />
     * @param address 起始地址
     * @param value 写入值
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, String value);

    /**
     * 写入指定长度的字符串信息，如果超出，就截断字符串，如果长度不足，那就补0操作，编码为ASCII<br />
     * @param address 起始地址
     * @param value 写入值
     * @param length 写入的字符串的长度
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, String value, int length);

    /**
     * 写入字符串信息，需要指定的编码信息<br />
     * @param address 起始地址
     * @param value 写入值
     * @param encoding 指定的编码信息
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, String value, String encoding );

    /**
     * 写入指定长度的字符串信息，如果超出，就截断字符串，如果长度不足，那就补0操作，编码为指定的编码信息<br />
     * @param address 起始地址
     * @param value 写入值
     * @param length 字符串的长度
     * @param encoding 指定的编码信息
     * @return 带有成功标识的结果类对象
     */
    OperateResult write(String address, String value, int length, String encoding );

    /**
     * 写入自定义类型的数据
     * @param address 起始地址
     * @param value 写入值
     * @param <T> 类型对象
     * @return 带有成功标识的结果类对象
     */
    <T extends IDataTransfer> OperateResult writeCustomer(String address, T value);

}
